package cn.yunyichina.utils.commons;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

public class DateUtils {


    public static String dateToString(Date date) {
        SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        dateformat.format(date);
        String strDate = dateformat.format(date);
        return strDate;
    }
    
    public static String getBetweenDay(int days){
		 Date date=new Date();
		 Calendar calendar = new GregorianCalendar();
		 calendar.setTime(date);
		 calendar.add(calendar.DATE,days);
		 date=calendar.getTime(); 
		 SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		 String dateString = formatter.format(date);
		 return dateString;
	 }


    public static String dateToStringNoFlit(Date date) {
        SimpleDateFormat dateformat = new SimpleDateFormat("yyyyMMddHHmmss");
        dateformat.format(date);
        String strDate = dateformat.format(date);
        return strDate;
    }

    public static String dateToString_yyMMddHHmmss(Date date) {
        SimpleDateFormat dateformat = new SimpleDateFormat("yyMMddHHmmss");
        dateformat.format(date);
        String strDate = dateformat.format(date);
        return strDate;
    }


    public static Date StringToDate(String dateStr) {
        SimpleDateFormat sdf = null;
        Date date = new Date();
        if (dateStr.length() > 10) {
            if (dateStr.indexOf("T") > -1) {
                dateStr = dateStr.replace("T", " ");
            }
            sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        } else {
            sdf = new SimpleDateFormat("yyyy-MM-dd");
        }
        try {
            date = sdf.parse(dateStr);
        } catch (java.text.ParseException e) {
            e.printStackTrace();
            return date;
        }
        return date;
    }


    public static Date StringToDateYMD(String dateStr) {
        Date date = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            date = sdf.parse(dateStr);
        } catch (java.text.ParseException e) {
            e.printStackTrace();
            return null;
        }
        return date;
    }

    public static String StringToDateYMDNotFilter(Date date) {
        SimpleDateFormat dateformat = new SimpleDateFormat("yyyyMMdd");
        dateformat.format(date);
        String strDate = dateformat.format(date);
        return strDate;
    }

    public static String strToDateTimeYMDHMSNotFilter(String datestr) {
        SimpleDateFormat dateformat = new SimpleDateFormat("yyyyMMddHHmmss");
        Date date = null;
        try {
            date = dateformat.parse(datestr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        String strDate = dateToString(date);
        return strDate;
    }

    public static String StringToTimeHMSSSSNotFilter(Date date) {
        SimpleDateFormat dateformat = new SimpleDateFormat("HHmmssSSS");
        dateformat.format(date);
        String strDate = dateformat.format(date);
        return strDate;
    }


    public static String StringToYMDHMSSSSNotFilter(Date date) {
        SimpleDateFormat dateformat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        dateformat.format(date);
        String strDate = dateformat.format(date);
        return strDate;
    }


    public static String generateFileName(String fileName) {
        DateFormat format = new SimpleDateFormat("yyMMddHHmmss");
        String formatDate = format.format(new Date());

        int random = new Random().nextInt(10000);

        int position = fileName.lastIndexOf(".");
        String extension = fileName.substring(position);

        return formatDate + random + extension;
    }


    public static Date yesterdayDate() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DATE, -1);
        return StringToDate(sdf.format(c.getTime()));
    }

 
    public static String today() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        return sdf.format(c.getTime());
    }


    public static String toChday() {
        Date d = new Date();
        SimpleDateFormat sdfy = new SimpleDateFormat("yyyy");
        SimpleDateFormat sdfm = new SimpleDateFormat("MM");
        SimpleDateFormat sdfd = new SimpleDateFormat("dd");
        return sdfy.format(d) + "年" + sdfm.format(d) + "月" + sdfd.format(d) + "日";
    }


    public static String tomorrowDate() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DATE, +1);
        return sdf.format(c.getTime());
    }

    public static String lastMonthDate() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, -1);
        return sdf.format(c.getTime());
    }


    public static String getDayDate(Integer day) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DATE, day);
        return sdf.format(c.getTime());
    }

 
    public static int getDaysBetween(Calendar d1, Calendar d2) {
        if (d1.after(d2)) {
            java.util.Calendar swap = d1;
            d1 = d2;
            d2 = swap;
        }
        int days = d2.get(Calendar.DAY_OF_YEAR) - d1.get(Calendar.DAY_OF_YEAR);
        int y2 = d2.get(Calendar.YEAR);
        if (d1.get(Calendar.YEAR) != y2) {
            d1 = (Calendar) d1.clone();
            do {
                // 得到当年的实际天数
                days += d1.getActualMaximum(Calendar.DAY_OF_YEAR);
                d1.add(Calendar.YEAR, 1);
            } while (d1.get(Calendar.YEAR) != y2);
        }
        return days;
    }

 
    public static Calendar date2Calendar(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal;
    }


    public static int YearOfWeekDay() {
        @SuppressWarnings("unused")
        Date d = new Date();
        Calendar cal = Calendar.getInstance();
        return cal.get(Calendar.WEEK_OF_YEAR);
    }


    public static int MonthOfWeekDay() {
        Calendar cal = Calendar.getInstance();
        return cal.get(Calendar.WEEK_OF_MONTH);
    }

 
    public static int getIntervalDays(Date startday, Date endday) {
        if (startday.after(endday)) {
            Date cal = startday;
            startday = endday;
            endday = cal;
        }
        long sl = startday.getTime();
        long el = endday.getTime();
        long ei = el - sl;
        return (int) (ei / (1000 * 60 * 60 * 24));
    }


    public static long DateDiff(Date startDate, Date endDate) {
        long totalDate = 0;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        long timestart = calendar.getTimeInMillis();
        calendar.setTime(endDate);
        long timeend = calendar.getTimeInMillis();
        totalDate = (timeend - timestart) / (1000 * 60 * 60 * 24);
        return totalDate;
    }

 
    public static String formatDate(Date date) {
        // 保存改后的时间
        String ymd = " ";
        if (date == null || "".equals(date) || "1900-01-01 00:00:00.0".equals(date)) {
            return ymd;
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        ymd = dateFormat.format(date);
        return ymd;
    }

    public static Date getNextMonth(Date nowdate, int delay) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        Calendar temp = Calendar.getInstance();
        temp.setTime(nowdate);
        int oldMonth = temp.get(Calendar.MONTH);
        int newMonth = oldMonth + delay;
        int oldYear = temp.get(Calendar.YEAR);
        int i, j;
        if (newMonth > 12) {
            i = newMonth % 12;
            j = newMonth / 12;
            temp.set(Calendar.MONTH, i);
            temp.set(Calendar.YEAR, j + oldYear);
        } else {
            temp.set(Calendar.MONTH, newMonth);
        }

        temp.set(Calendar.DATE, temp.get(Calendar.DATE));
        String dateString = formatter.format(temp.getTime());
        Date strtodate = null;
        try {
            strtodate = formatter.parse(dateString);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return strtodate;
    }

    public static String formatDate(String str, String sourceFormat, String desFormat) {
        SimpleDateFormat formatter = new SimpleDateFormat(sourceFormat);
        try {
            Date date = formatter.parse(str);
            formatter = new SimpleDateFormat(desFormat);
            return formatter.format(date);
        } catch (ParseException e) {
            e.printStackTrace();
            return "";
        }
    }

 
    public static String getDateStr(Date date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        return dateFormat.format(date);
    }


    public static String getDateTimeStr() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return dateFormat.format(Calendar.getInstance().getTime());
    }


    public static Date getDateBegin(Date date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            return dateFormat.parse(getDateStr(date) + " 00:00:00");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

  
    public static Date getDateEnd(Date date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            return dateFormat.parse(getDateStr(date) + " 23:59:59");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }


    public static String getDayForDate(Date date, Integer day) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.DATE, day);
        return sdf.format(c.getTime());
    }

    public static String getStringDayAfter(String dateStr,Integer day){
        SimpleDateFormat sdf = null;
        Date date = null;
        if (dateStr.length() > 10) {
            if (dateStr.indexOf("T") > -1) {
                dateStr = dateStr.replace("T", " ");
            }
            sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        } else {
            sdf = new SimpleDateFormat("yyyy-MM-dd");
        }
        try {
            date = sdf.parse(dateStr);
            Calendar c = Calendar.getInstance();
            c.setTime(date);
            c.add(Calendar.DATE, day);
            return sdf.format(c.getTime());
        } catch (java.text.ParseException e) {
            e.printStackTrace();
            return null;
        }
    }


    public static String getDateForType(String date, int type) {
        SimpleDateFormat myFmt = null;
        Calendar rightNow = null;
        try {
            myFmt = new SimpleDateFormat("yyyy-MM-dd");
            String exDate = "";
            rightNow = Calendar.getInstance();
            rightNow.setTime(myFmt.parse(date));
            if (type == 1) {
                rightNow.add(Calendar.DAY_OF_YEAR, 1);// 日期加1天
            } else if (type == 2) {
                rightNow.add(Calendar.DAY_OF_YEAR, -1);// 日期1天
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return myFmt.format(rightNow.getTime());
    }

    // --------------------------------------------------------------

    public static final String YYYYMMDD = "yyyy-MM-dd";
    public static final String YYYYMMDDHH = "yyyy-MM-dd HH";
    public static final String YYYYMMDDHHMM = "yyyy-MM-dd HH:mm";
    public static final String YYYYMMDDHHMMSS = "yyyy-MM-dd HH:mm:ss";

    public static final String YYYYMMDDHHMMSS_NOBAR = "yyyyMMddHHmmss";

    public static String getDatetime() {
        return getDatetime(null);
    }

    public static String getDatetime(String pattern) {
        if (pattern == null) {
            DateFormat formatter = new SimpleDateFormat(YYYYMMDDHHMMSS);
            return formatter.format(Calendar.getInstance().getTime());
        } else {
            return new SimpleDateFormat(pattern).format(Calendar.getInstance().getTime());
        }
    }

    public static String parseDatetime(String str, String pattern) {
        DateFormat formatter = new SimpleDateFormat(pattern);
        String result = null;
        try {
            result = new SimpleDateFormat(YYYYMMDDHHMMSS).format(formatter.parse(str));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return result;
    }



    public static List<Date> getDatesBetweenTwoDate(Date beginDate, Date endDate) {
    	SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
    	Map<String,Date> map = new LinkedHashMap<>();
        List<Date> lDate = new ArrayList<Date>();
        lDate.add(beginDate);// 把开始时间加入集合
        Calendar cal = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        cal.setTime(beginDate);
        map.put(dateformat.format(cal.getTime()), cal.getTime());
        boolean bContinue = true;
        while (bContinue) {
            // 根据日历的规则，为给定的日历字段添加或减去指定的时间量
            cal.add(Calendar.DAY_OF_MONTH, 1);
            // 测试此日期是否在指定日期之后
            if (endDate.after(cal.getTime())) {
                lDate.add(cal.getTime());
                map.put(dateformat.format(cal.getTime()), cal.getTime());
            } else {
                break;
            }
        }
        lDate.add(endDate);// 把结束时间加入集合
        map.put(dateformat.format(endDate), endDate);
//        HashSet<Date> dates = new HashSet<Date>(lDate);
//        return new ArrayList<Date>(dates);
        return Arrays.asList(map.values().toArray(new Date[map.size()]));
    }

 
    public static int daysBetween(Date smdate, Date bdate) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        smdate = sdf.parse(sdf.format(smdate));
        bdate = sdf.parse(sdf.format(bdate));
        Calendar cal = Calendar.getInstance();
        cal.setTime(smdate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(bdate);
        long time2 = cal.getTimeInMillis();
        long between_days = (time2 - time1) / (1000 * 3600 * 24);

        return Integer.parseInt(String.valueOf(between_days));
    }

    /**
     * 字符串的日期格式的计算
     */
    public static int daysBetween(String smdate, String bdate) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        cal.setTime(sdf.parse(smdate));
        long time1 = cal.getTimeInMillis();
        cal.setTime(sdf.parse(bdate));
        long time2 = cal.getTimeInMillis();
        long between_days = (time2 - time1) / (1000 * 3600 * 24);

        return Integer.parseInt(String.valueOf(between_days));
    }

    /**
     * 取当前时间前后天
     * @param day
     * @return
     */
    public static String getDaysBetween(Date date, Integer day) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.DAY_OF_MONTH, day);
        return sdf.format(c.getTime());
    }

    /**
     * 取当前时间前后小时
     * @param hours
     * @return
     */
    public static String getTimesBetween(Date date, Integer hours) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.HOUR, hours);
        return sdf.format(c.getTime());
    }


    /**
     * 取当前时间前后秒
     * @param second
     * @return
     */
    public static String getSecondsBetween(Date date, Integer second) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.SECOND, second);
        return sdf.format(c.getTime());
    }

    public static void main(String[] args) throws ParseException {
//        Date now_10 = new Date(System.currentTimeMillis() - 30 * 60 * 1000);
//        String date1 = dateToString(now_10);
        System.out.println(getDaysBetween(new Date() , -1));
    }


}
